റിയാക്ട് ഫൈബറിന്റെ പ്രയോറിറ്റി ലെയ്ൻ മാനേജ്മെന്റിൽ വൈദഗ്ദ്ധ്യം നേടിക്കൊണ്ട് സുഗമമായ യൂസർ ഇന്റർഫേസുകൾ നിർമ്മിക്കാം. കൺകറന്റ് റെൻഡറിംഗ്, ഷെഡ്യൂളർ, startTransition പോലുള്ള പുതിയ API-കളെക്കുറിച്ചുള്ള ഒരു സമ്പൂർണ്ണ ഗൈഡ്.
റിയാക്ട് ഫൈബർ പ്രയോറിറ്റി ലെയ്ൻ മാനേജ്മെന്റ്: റെൻഡറിംഗ് നിയന്ത്രണത്തിലേക്കുള്ള ഒരു ആഴത്തിലുള്ള பார்வை
വെബ് ഡെവലപ്മെന്റിന്റെ ലോകത്ത്, ഉപയോക്തൃ അനുഭവമാണ് ഏറ്റവും പ്രധാനം. ഒരു ചെറിയ ഫ്രീസ്, മുടന്തുന്ന ആനിമേഷൻ, അല്ലെങ്കിൽ പ്രതികരിക്കാൻ താമസിക്കുന്ന ഒരു ഇൻപുട്ട് ഫീൽഡ് എന്നിവ ഒരു സന്തുഷ്ടനായ ഉപയോക്താവിനെയും നിരാശനായ ഉപയോക്താവിനെയും തമ്മിൽ വേർതിരിക്കും. വർഷങ്ങളായി, സുഗമവും പ്രതികരണശേഷിയുള്ളതുമായ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കാൻ ഡെവലപ്പർമാർ ബ്രൗസറിന്റെ സിംഗിൾ-ത്രെഡ് സ്വഭാവത്തോട് പോരാടുകയായിരുന്നു. റിയാക്ട് 16-ൽ ഫൈബർ ആർക്കിടെക്ചർ അവതരിപ്പിച്ചതോടെയും, റിയാക്ട് 18-ലെ കൺകറന്റ് ഫീച്ചറുകളിലൂടെ അതിന്റെ പൂർണ്ണമായ സാക്ഷാത്കാരത്തോടെയും, ഈ രംഗം അടിസ്ഥാനപരമായി മാറി. റിയാക്ട് വെറുമൊരു UI റെൻഡർ ചെയ്യുന്ന ലൈബ്രറിയിൽ നിന്ന് UI അപ്ഡേറ്റുകളെ ബുദ്ധിപരമായി ഷെഡ്യൂൾ ചെയ്യുന്ന ഒന്നായി പരിണമിച്ചു.
ഈ ആഴത്തിലുള്ള പഠനം ഈ പരിണാമത്തിന്റെ ഹൃദയഭാഗം പര്യവേക്ഷണം ചെയ്യുന്നു: റിയാക്ട് ഫൈബറിന്റെ പ്രയോറിറ്റി ലെയ്ൻ മാനേജ്മെന്റ്. ഇപ്പോൾ എന്ത് റെൻഡർ ചെയ്യണം, എന്തിന് കാത്തിരിക്കാം, യൂസർ ഇന്റർഫേസ് ഫ്രീസ് ചെയ്യാതെ ഒന്നിലധികം സ്റ്റേറ്റ് അപ്ഡേറ്റുകൾ എങ്ങനെ കൈകാര്യം ചെയ്യുന്നു എന്നതിനെക്കുറിച്ചുള്ള നിഗൂഢതകൾ നമ്മൾ ഇവിടെ നീക്കും. ഇത് വെറുമൊരു അക്കാദമിക് പഠനമല്ല; ഈ പ്രധാന തത്വങ്ങൾ മനസ്സിലാക്കുന്നത് ആഗോള പ്രേക്ഷകർക്കായി വേഗതയേറിയതും മികച്ചതും കൂടുതൽ കരുത്തുറ്റതുമായ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കാൻ നിങ്ങളെ പ്രാപ്തരാക്കും.
സ്റ്റാക്ക് റീകൺസൈലറിൽ നിന്ന് ഫൈബറിലേക്ക്: മാറ്റിയെഴുതിയതിന് പിന്നിലെ 'എന്തുകൊണ്ട്'
ഫൈബറിന്റെ പുതുമയെ അഭിനന്ദിക്കുന്നതിന്, അതിന്റെ മുൻഗാമിയായ സ്റ്റാക്ക് റീകൺസൈലറിന്റെ പരിമിതികൾ നമ്മൾ ആദ്യം മനസ്സിലാക്കണം. റിയാക്ട് 16-ന് മുമ്പ്, റീകൺസിലിയേഷൻ പ്രക്രിയ — DOM-ൽ എന്ത് മാറ്റം വരുത്തണമെന്ന് നിർണ്ണയിക്കാൻ റിയാക്ട് ഒരു ട്രീയെ മറ്റൊന്നുമായി താരതമ്യം ചെയ്യാൻ ഉപയോഗിക്കുന്ന അൽഗോരിതം — സിൻക്രണസും റിക്കേഴ്സീവും ആയിരുന്നു. ഒരു കമ്പോണന്റിന്റെ സ്റ്റേറ്റ് അപ്ഡേറ്റ് ചെയ്യുമ്പോൾ, റിയാക്ട് മുഴുവൻ കമ്പോണന്റ് ട്രീയിലൂടെയും കടന്നുപോകുകയും, മാറ്റങ്ങൾ കണക്കാക്കുകയും, അവയെല്ലാം ഒറ്റയടിക്ക്, തടസ്സമില്ലാതെ DOM-ൽ പ്രയോഗിക്കുകയും ചെയ്യുമായിരുന്നു.
ചെറിയ ആപ്ലിക്കേഷനുകൾക്ക് ഇത് പ്രശ്നമായിരുന്നില്ല. എന്നാൽ ആഴത്തിലുള്ള കമ്പോണന്റ് ട്രീകളുള്ള സങ്കീർണ്ണമായ UI-കളിൽ, ഈ പ്രക്രിയയ്ക്ക് ഗണ്യമായ സമയം എടുത്തേക്കാം — ഉദാഹരണത്തിന്, 16 മില്ലിസെക്കൻഡിൽ കൂടുതൽ. ജാവാസ്ക്രിപ്റ്റ് സിംഗിൾ-ത്രെഡ് ആയതിനാൽ, ദൈർഘ്യമേറിയ ഒരു റീകൺസിലിയേഷൻ ടാസ്ക് പ്രധാന ത്രെഡിനെ ബ്ലോക്ക് ചെയ്യും. ഇതിനർത്ഥം ബ്രൗസറിന് മറ്റ് നിർണായക ജോലികൾ കൈകാര്യം ചെയ്യാൻ കഴിയില്ല, അവയിൽ ചിലത്:
- ഉപയോക്താവിന്റെ ഇൻപുട്ടുകളോട് പ്രതികരിക്കുക (ടൈപ്പിംഗ് അല്ലെങ്കിൽ ക്ലിക്കിംഗ് പോലുള്ളവ).
- ആനിമേഷനുകൾ പ്രവർത്തിപ്പിക്കുക (CSS അല്ലെങ്കിൽ ജാവാസ്ക്രിപ്റ്റ് അടിസ്ഥാനമാക്കിയുള്ളവ).
- സമയം പ്രധാനമായ മറ്റ് ലോജിക്കുകൾ നടപ്പിലാക്കുക.
ഇതിന്റെ ഫലം "ജാങ്ക്" എന്നറിയപ്പെടുന്ന ഒരു പ്രതിഭാസമായിരുന്നു — ഇടയ്ക്കിടെ നിലച്ചുപോകുന്ന, പ്രതികരണശേഷിയില്ലാത്ത ഒരു ഉപയോക്തൃ അനുഭവം. സ്റ്റാക്ക് റീകൺസൈലർ ഒരു സിംഗിൾ-ട്രാക്ക് റെയിൽവേ പോലെയായിരുന്നു പ്രവർത്തിച്ചിരുന്നത്: ഒരു ട്രെയിൻ (ഒരു റെൻഡർ അപ്ഡേറ്റ്) യാത്ര തുടങ്ങിയാൽ, അത് പൂർത്തിയാകുന്നതുവരെ ഓടണം, മറ്റൊരു ട്രെയിനിനും ആ ട്രാക്ക് ഉപയോഗിക്കാൻ കഴിയില്ലായിരുന്നു. ഈ തടസ്സപ്പെടുത്തുന്ന സ്വഭാവമാണ് റിയാക്ടിന്റെ കോർ അൽഗോരിതം പൂർണ്ണമായും മാറ്റിയെഴുതുന്നതിനുള്ള പ്രധാന പ്രേരണയായത്.
റിയാക്ട് ഫൈബറിന് പിന്നിലെ പ്രധാന ആശയം, റീകൺസിലിയേഷനെ ചെറിയ ജോലികളായി വിഭജിക്കാൻ കഴിയുന്ന ഒന്നായി പുനർവിചിന്തനം ചെയ്യുക എന്നതായിരുന്നു. ഒരൊറ്റ, വലിയ ടാസ്കിന് പകരം, റെൻഡറിംഗ് താൽക്കാലികമായി നിർത്താനും, പുനരാരംഭിക്കാനും, റദ്ദാക്കാനും പോലും കഴിയും. സിൻക്രണസിൽ നിന്ന് അസിൻക്രണസ്, ഷെഡ്യൂൾ ചെയ്യാവുന്ന ഒരു പ്രക്രിയയിലേക്കുള്ള ഈ മാറ്റം, റിയാക്ടിന് ബ്രൗസറിന്റെ പ്രധാന ത്രെഡിലേക്ക് നിയന്ത്രണം തിരികെ നൽകാൻ അനുവദിക്കുന്നു, ഇത് ഉപയോക്തൃ ഇൻപുട്ട് പോലുള്ള ഉയർന്ന മുൻഗണനയുള്ള ജോലികൾ ഒരിക്കലും തടസ്സപ്പെടുന്നില്ലെന്ന് ഉറപ്പാക്കുന്നു. ഫൈബർ സിംഗിൾ-ട്രാക്ക് റെയിൽവേയെ ഉയർന്ന മുൻഗണനയുള്ള ട്രാഫിക്കിനായി എക്സ്പ്രസ് ലെയ്നുകളുള്ള ഒരു മൾട്ടി-ലെയ്ൻ ഹൈവേയാക്കി മാറ്റി.
എന്താണ് ഒരു 'ഫൈബർ'? കൺകറൻസിയുടെ അടിസ്ഥാന ഘടകം
അടിസ്ഥാനപരമായി, ഒരു "ഫൈബർ" എന്നത് ഒരു യൂണിറ്റ് ജോലിയെ പ്രതിനിധീകരിക്കുന്ന ഒരു ജാവാസ്ക്രിപ്റ്റ് ഒബ്ജക്റ്റാണ്. അതിൽ ഒരു കമ്പോണന്റിനെക്കുറിച്ചുള്ള വിവരങ്ങൾ, അതിന്റെ ഇൻപുട്ട് (props), ഔട്ട്പുട്ട് (children) എന്നിവ അടങ്ങിയിരിക്കുന്നു. ഒരു ഫൈബറിനെ നിങ്ങൾക്ക് ഒരു വെർച്വൽ സ്റ്റാക്ക് ഫ്രെയിം ആയി കണക്കാക്കാം. പഴയ സ്റ്റാക്ക് റീകൺസൈലറിൽ, റിക്കേഴ്സീവ് ട്രീ ട്രാവേഴ്സൽ നിയന്ത്രിക്കാൻ ബ്രൗസറിന്റെ കോൾ സ്റ്റാക്ക് ഉപയോഗിച്ചിരുന്നു. ഫൈബർ ഉപയോഗിച്ച്, റിയാക്ട് സ്വന്തമായി ഒരു വെർച്വൽ സ്റ്റാക്ക് നടപ്പിലാക്കുന്നു, ഇത് ഫൈബർ നോഡുകളുടെ ഒരു ലിങ്ക്ഡ് ലിസ്റ്റ് വഴി പ്രതിനിധീകരിക്കുന്നു. ഇത് റെൻഡറിംഗ് പ്രക്രിയയിൽ റിയാക്ടിന് പൂർണ്ണ നിയന്ത്രണം നൽകുന്നു.
നിങ്ങളുടെ കമ്പോണന്റ് ട്രീയിലെ ഓരോ ഘടകത്തിനും അനുബന്ധമായ ഒരു ഫൈബർ നോഡ് ഉണ്ട്. ഈ നോഡുകൾ ഒരുമിച്ച് ചേർന്ന് ഒരു ഫൈബർ ട്രീ രൂപീകരിക്കുന്നു, അത് കമ്പോണന്റ് ട്രീ ഘടനയെ പ്രതിഫലിപ്പിക്കുന്നു. ഒരു ഫൈബർ നോഡിൽ നിർണ്ണായകമായ വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു, അവയിൽ ചിലത്:
- type, key: കമ്പോണന്റിന്റെ ഐഡന്റിഫയറുകൾ, റിയാക്ട് എലമെന്റിൽ കാണുന്നതിന് സമാനം.
- child: അതിന്റെ ആദ്യത്തെ ചൈൽഡ് ഫൈബറിലേക്കുള്ള ഒരു പോയിന്റർ.
- sibling: അതിന്റെ അടുത്ത സിബ്ലിംഗ് ഫൈബറിലേക്കുള്ള ഒരു പോയിന്റർ.
- return: അതിന്റെ പാരന്റ് ഫൈബറിലേക്കുള്ള ഒരു പോയിന്റർ (ജോലി പൂർത്തിയാക്കിയതിന് ശേഷമുള്ള 'റിട്ടേൺ' പാത്ത്).
- pendingProps, memoizedProps: താരതമ്യത്തിനായി ഉപയോഗിക്കുന്ന, മുമ്പത്തേയും അടുത്ത റെൻഡറിലേയും പ്രോപ്പുകൾ.
- stateNode: യഥാർത്ഥ DOM നോഡ്, ക്ലാസ് ഇൻസ്റ്റൻസ്, അല്ലെങ്കിൽ അടിസ്ഥാന പ്ലാറ്റ്ഫോം എലമെന്റിലേക്കുള്ള ഒരു റഫറൻസ്.
- effectTag: ചെയ്യേണ്ട ജോലിയെ വിവരിക്കുന്ന ഒരു ബിറ്റ്മാസ്ക് (ഉദാഹരണത്തിന്, Placement, Update, Deletion).
ഈ ഘടന റിയാക്ടിന് നേറ്റീവ് റിക്കർഷനെ ആശ്രയിക്കാതെ ട്രീയിലൂടെ സഞ്ചരിക്കാൻ അനുവദിക്കുന്നു. അതിന് ഒരു ഫൈബറിൽ ജോലി തുടങ്ങാനും, താൽക്കാലികമായി നിർത്താനും, പിന്നീട് സ്ഥാനം നഷ്ടപ്പെടാതെ പുനരാരംഭിക്കാനും കഴിയും. ജോലി താൽക്കാലികമായി നിർത്താനും പുനരാരംഭിക്കാനുമുള്ള ഈ കഴിവാണ് റിയാക്ടിന്റെ എല്ലാ കൺകറന്റ് ഫീച്ചറുകളെയും സാധ്യമാക്കുന്ന അടിസ്ഥാന സംവിധാനം.
സിസ്റ്റത്തിന്റെ ഹൃദയം: ഷെഡ്യൂളറും പ്രയോറിറ്റി ലെവലുകളും
ഫൈബറുകൾ ജോലിയുടെ യൂണിറ്റുകളാണെങ്കിൽ, ഏത് ജോലി എപ്പോൾ ചെയ്യണമെന്ന് തീരുമാനിക്കുന്ന തലച്ചോറാണ് ഷെഡ്യൂളർ. ഒരു സ്റ്റേറ്റ് മാറ്റം വന്നാലുടൻ റിയാക്ട് റെൻഡറിംഗ് ആരംഭിക്കുകയല്ല ചെയ്യുന്നത്. പകരം, അത് അപ്ഡേറ്റിന് ഒരു പ്രയോറിറ്റി ലെവൽ നൽകുകയും അത് കൈകാര്യം ചെയ്യാൻ ഷെഡ്യൂളറോട് ആവശ്യപ്പെടുകയും ചെയ്യുന്നു. ഷെഡ്യൂളർ പിന്നീട് ബ്രൗസറുമായി ചേർന്ന് ആ ജോലി ചെയ്യാൻ ഏറ്റവും അനുയോജ്യമായ സമയം കണ്ടെത്തുന്നു, അത് കൂടുതൽ പ്രധാനപ്പെട്ട ജോലികളെ തടസ്സപ്പെടുത്തുന്നില്ലെന്ന് ഉറപ്പാക്കുന്നു.
തുടക്കത്തിൽ, ഈ സിസ്റ്റം ഒരു കൂട്ടം പ്രത്യേക പ്രയോറിറ്റി ലെവലുകൾ ഉപയോഗിച്ചിരുന്നു. ആധുനിക നിർവ്വഹണം (ലെയ്ൻ മോഡൽ) കൂടുതൽ സൂക്ഷ്മമാണെങ്കിലും, ഈ ആശയപരമായ ലെവലുകൾ മനസ്സിലാക്കുന്നത് ഒരു നല്ല തുടക്കമാണ്:
- ImmediatePriority: ഇത് ഏറ്റവും ഉയർന്ന പ്രയോറിറ്റിയാണ്, ഉടനടി സംഭവിക്കേണ്ട സിൻക്രണസ് അപ്ഡേറ്റുകൾക്കായി നീക്കിവച്ചിരിക്കുന്നു. ഒരു കൺട്രോൾഡ് ഇൻപുട്ട് ഇതിന്റെ ഒരു മികച്ച ഉദാഹരണമാണ്. ഒരു ഉപയോക്താവ് ഒരു ഇൻപുട്ട് ഫീൽഡിൽ ടൈപ്പ് ചെയ്യുമ്പോൾ, UI ആ മാറ്റം തൽക്ഷണം പ്രതിഫലിപ്പിക്കണം. ഏതാനും മില്ലിസെക്കൻഡ് വൈകിയാൽ പോലും, ഇൻപുട്ട് ലാഗ് ചെയ്യുന്നതായി അനുഭവപ്പെടും.
- UserBlockingPriority: ഒരു ബട്ടൺ ക്ലിക്കുചെയ്യുകയോ സ്ക്രീനിൽ ടാപ്പുചെയ്യുകയോ പോലുള്ള ഉപയോക്തൃ ഇടപെടലുകളുടെ ഫലമായുണ്ടാകുന്ന അപ്ഡേറ്റുകൾക്ക് വേണ്ടിയുള്ളതാണിത്. ഇവ ഉപയോക്താവിന് ഉടനടി അനുഭവപ്പെടണം, എന്നാൽ ആവശ്യമെങ്കിൽ വളരെ ചെറിയൊരു കാലയളവിലേക്ക് മാറ്റിവയ്ക്കാം. മിക്ക ഇവന്റ് ഹാൻഡ്ലറുകളും ഈ പ്രയോറിറ്റിയിൽ അപ്ഡേറ്റുകൾ ട്രിഗർ ചെയ്യുന്നു.
- NormalPriority: ഡാറ്റാ ഫെച്ചുകൾ (`useEffect`), നാവിഗേഷൻ എന്നിവയിൽ നിന്നുള്ള അപ്ഡേറ്റുകൾ പോലുള്ള മിക്ക അപ്ഡേറ്റുകൾക്കുമുള്ള ഡിഫോൾട്ട് പ്രയോറിറ്റിയാണിത്. ഈ അപ്ഡേറ്റുകൾ തൽക്ഷണമാകേണ്ട ആവശ്യമില്ല, ഉപയോക്തൃ ഇടപെടലുകളിൽ തടസ്സമുണ്ടാകാതിരിക്കാൻ റിയാക്ടിന് അവ ഷെഡ്യൂൾ ചെയ്യാൻ കഴിയും.
- LowPriority: ഓഫ്സ്ക്രീൻ ഉള്ളടക്കം റെൻഡർ ചെയ്യുകയോ അനലിറ്റിക്സ് ഇവന്റുകൾ പോലുള്ള സമയ-സെൻസിറ്റീവ് അല്ലാത്ത അപ്ഡേറ്റുകൾക്ക് വേണ്ടിയുള്ളതാണിത്.
- IdlePriority: ഏറ്റവും കുറഞ്ഞ പ്രയോറിറ്റി, ബ്രൗസർ പൂർണ്ണമായും നിഷ്ക്രിയമായിരിക്കുമ്പോൾ മാത്രം ചെയ്യാൻ കഴിയുന്ന ജോലികൾക്ക് വേണ്ടിയുള്ളതാണ്. ഇത് ആപ്ലിക്കേഷൻ കോഡ് നേരിട്ട് ഉപയോഗിക്കുന്നത് വിരളമാണ്, എന്നാൽ ലോഗിംഗ് അല്ലെങ്കിൽ ഭാവിയിലെ ജോലികൾ മുൻകൂട്ടി കണക്കാക്കുന്നത് പോലുള്ള കാര്യങ്ങൾക്കായി ആന്തരികമായി ഉപയോഗിക്കുന്നു.
അപ്ഡേറ്റിന്റെ സന്ദർഭത്തെ അടിസ്ഥാനമാക്കി റിയാക്ട് യാന്ത്രികമായി ശരിയായ പ്രയോറിറ്റി നൽകുന്നു. ഉദാഹരണത്തിന്, ഒരു `click` ഇവന്റ് ഹാൻഡ്ലറിനുള്ളിലെ ഒരു അപ്ഡേറ്റ് `UserBlockingPriority` ആയി ഷെഡ്യൂൾ ചെയ്യപ്പെടുന്നു, അതേസമയം `useEffect`-നുള്ളിലെ ഒരു അപ്ഡേറ്റ് സാധാരണയായി `NormalPriority` ആയിരിക്കും. ഈ ബുദ്ധിപരമായ, സന്ദർഭത്തിനനുസരിച്ചുള്ള മുൻഗണനാക്രമീകരണമാണ് റിയാക്ടിന് വേഗതയുള്ള അനുഭവം നൽകുന്നത്.
ലെയ്ൻ തിയറി: ആധുനിക പ്രയോറിറ്റി മോഡൽ
റിയാക്ടിന്റെ കൺകറന്റ് ഫീച്ചറുകൾ കൂടുതൽ സങ്കീർണ്ണമായപ്പോൾ, ലളിതമായ സംഖ്യാ പ്രയോറിറ്റി സിസ്റ്റം അപര്യാപ്തമാണെന്ന് തെളിഞ്ഞു. വ്യത്യസ്ത പ്രയോറിറ്റികളുള്ള ഒന്നിലധികം അപ്ഡേറ്റുകൾ, തടസ്സപ്പെടുത്തലുകൾ, ബാച്ചിംഗ് തുടങ്ങിയ സങ്കീർണ്ണമായ സാഹചര്യങ്ങൾ ഭംഗിയായി കൈകാര്യം ചെയ്യാൻ അതിന് കഴിഞ്ഞില്ല. ഇത് **ലെയ്ൻ മോഡലിന്റെ** വികാസത്തിലേക്ക് നയിച്ചു.
ഒരൊറ്റ പ്രയോറിറ്റി നമ്പറിന് പകരം, 31 "ലെയ്നുകളുടെ" ഒരു കൂട്ടം സങ്കൽപ്പിക്കുക. ഓരോ ലെയ്നും ഓരോ പ്രയോറിറ്റിയെ പ്രതിനിധീകരിക്കുന്നു. ഇത് ഒരു ബിറ്റ്മാസ്ക് ആയി നടപ്പിലാക്കിയിരിക്കുന്നു — ഓരോ ബിറ്റും ഒരു ലെയ്നുമായി ബന്ധപ്പെട്ടിരിക്കുന്ന ഒരു 31-ബിറ്റ് ഇന്റിജർ. ഈ ബിറ്റ്മാസ്ക് സമീപനം വളരെ കാര്യക്ഷമവും ശക്തമായ പ്രവർത്തനങ്ങൾക്ക് അനുവദിക്കുന്നതുമാണ്:
- ഒന്നിലധികം പ്രയോറിറ്റികളെ പ്രതിനിധീകരിക്കൽ: ഒരു സിംഗിൾ ബിറ്റ്മാസ്കിന് ഒരു കൂട്ടം പെൻഡിംഗ് പ്രയോറിറ്റികളെ പ്രതിനിധീകരിക്കാൻ കഴിയും. ഉദാഹരണത്തിന്, ഒരു കമ്പോണന്റിൽ ഒരു `UserBlocking` അപ്ഡേറ്റും ഒരു `Normal` അപ്ഡേറ്റും പെൻഡിംഗ് ആണെങ്കിൽ, അതിന്റെ `lanes` പ്രോപ്പർട്ടിയിൽ ആ രണ്ട് പ്രയോറിറ്റികളുടെയും ബിറ്റുകൾ 1 ആയി സജ്ജീകരിച്ചിരിക്കും.
- ഓവർലാപ്പ് പരിശോധിക്കൽ: രണ്ട് സെറ്റ് ലെയ്നുകൾ ഓവർലാപ്പ് ചെയ്യുന്നുണ്ടോയെന്നോ ഒരു സെറ്റ് മറ്റൊന്നിന്റെ ഉപവിഭാഗമാണോയെന്നോ പരിശോധിക്കാൻ ബിറ്റ്വൈസ് പ്രവർത്തനങ്ങൾ എളുപ്പമാക്കുന്നു. ഒരു പുതിയ അപ്ഡേറ്റ് നിലവിലുള്ള ജോലിയുമായി ബാച്ച് ചെയ്യാൻ കഴിയുമോ എന്ന് നിർണ്ണയിക്കാൻ ഇത് ഉപയോഗിക്കുന്നു.
- ജോലിക്ക് മുൻഗണന നൽകൽ: ഒരു കൂട്ടം പെൻഡിംഗ് ലെയ്നുകളിലെ ഏറ്റവും ഉയർന്ന പ്രയോറിറ്റിയുള്ള ലെയ്ൻ റിയാക്ടിന് വേഗത്തിൽ തിരിച്ചറിയാനും അതിൽ മാത്രം പ്രവർത്തിക്കാൻ തിരഞ്ഞെടുക്കാനും കഴിയും, കുറഞ്ഞ പ്രയോറിറ്റിയുള്ള ജോലികൾ തൽക്കാലം അവഗണിക്കുന്നു.
31 ലെയ്നുകളുള്ള ഒരു നീന്തൽക്കുളമായി ഇതിനെ ഉപമിക്കാം. ഒരു മത്സര നീന്തൽക്കാരനെപ്പോലെയുള്ള ഒരു അടിയന്തിര അപ്ഡേറ്റിന് ഉയർന്ന പ്രയോറിറ്റിയുള്ള ഒരു ലെയ്ൻ ലഭിക്കുകയും തടസ്സമില്ലാതെ മുന്നോട്ട് പോകുകയും ചെയ്യാം. സാധാരണ നീന്തൽക്കാരെപ്പോലെ അടിയന്തിരമല്ലാത്ത പല അപ്ഡേറ്റുകളും കുറഞ്ഞ പ്രയോറിറ്റിയുള്ള ലെയ്നിൽ ഒരുമിച്ച് ചേർക്കാം. ഒരു മത്സര നീന്തൽക്കാരൻ പെട്ടെന്ന് വന്നാൽ, ലൈഫ്ഗാർഡുകൾക്ക് (ഷെഡ്യൂളർ) മുൻഗണനയുള്ള നീന്തൽക്കാരനെ കടന്നുപോകാൻ അനുവദിക്കുന്നതിനായി സാധാരണ നീന്തൽക്കാരെ താൽക്കാലികമായി നിർത്താൻ കഴിയും. ഈ സങ്കീർണ്ണമായ ഏകോപനം കൈകാര്യം ചെയ്യുന്നതിനായി ലെയ്ൻ മോഡൽ റിയാക്ടിന് വളരെ സൂക്ഷ്മവും വഴക്കമുള്ളതുമായ ഒരു സംവിധാനം നൽകുന്നു.
രണ്ട്-ഘട്ട റീകൺസിലിയേഷൻ പ്രക്രിയ
റിയാക്ട് ഫൈബറിന്റെ മാന്ത്രികത അതിന്റെ രണ്ട്-ഘട്ട കമ്മിറ്റ് ആർക്കിടെക്ചറിലൂടെയാണ് യാഥാർത്ഥ്യമാകുന്നത്. ഈ വേർതിരിവാണ് റെൻഡറിംഗ് തടസ്സപ്പെടുത്താൻ അനുവദിക്കുന്നത്, അതേസമയം ദൃശ്യപരമായ പൊരുത്തക്കേടുകൾ ഉണ്ടാകുകയുമില്ല.
ഘട്ടം 1: റെൻഡർ/റീകൺസിലിയേഷൻ ഘട്ടം (അസിൻക്രണസും തടസ്സപ്പെടുത്താവുന്നതും)
റിയാക്ട് കഠിനാധ്വാനം ചെയ്യുന്നത് ഇവിടെയാണ്. കമ്പോണന്റ് ട്രീയുടെ റൂട്ടിൽ നിന്ന് ആരംഭിച്ച്, റിയാക്ട് ഒരു `workLoop`-ൽ ഫൈബർ നോഡുകളിലൂടെ സഞ്ചരിക്കുന്നു. ഓരോ ഫൈബറിനും, അത് അപ്ഡേറ്റ് ചെയ്യേണ്ടതുണ്ടോ എന്ന് നിർണ്ണയിക്കുന്നു. ഇത് നിങ്ങളുടെ കമ്പോണന്റുകളെ വിളിക്കുകയും, പുതിയ എലമെന്റുകളെ പഴയ ഫൈബറുകളുമായി താരതമ്യം ചെയ്യുകയും, സൈഡ് എഫക്റ്റുകളുടെ ഒരു ലിസ്റ്റ് നിർമ്മിക്കുകയും ചെയ്യുന്നു (ഉദാഹരണത്തിന്, "ഈ DOM നോഡ് ചേർക്കുക", "ഈ ആട്രിബ്യൂട്ട് അപ്ഡേറ്റ് ചെയ്യുക", "ഈ കമ്പോണന്റ് നീക്കം ചെയ്യുക").
ഈ ഘട്ടത്തിന്റെ നിർണ്ണായകമായ സവിശേഷത ഇത് അസിൻക്രണസും തടസ്സപ്പെടുത്താവുന്നതുമാണ് എന്നതാണ്. കുറച്ച് ഫൈബറുകൾ പ്രോസസ്സ് ചെയ്ത ശേഷം, `shouldYield` എന്ന ഒരു ആന്തരിക ഫംഗ്ഷൻ വഴി അതിന് അനുവദിച്ച സമയപരിധി (സാധാരണയായി കുറച്ച് മില്ലിസെക്കൻഡ്) കഴിഞ്ഞോ എന്ന് റിയാക്ട് പരിശോധിക്കുന്നു. ഉയർന്ന പ്രയോറിറ്റിയുള്ള ഒരു ഇവന്റ് (ഉപയോക്തൃ ഇൻപുട്ട് പോലുള്ളവ) സംഭവിച്ചിട്ടുണ്ടെങ്കിൽ അല്ലെങ്കിൽ അതിന്റെ സമയം കഴിഞ്ഞിട്ടുണ്ടെങ്കിൽ, റിയാക്ട് അതിന്റെ ജോലി താൽക്കാലികമായി നിർത്തി, ഫൈബർ ട്രീയിൽ അതിന്റെ പുരോഗതി സംരക്ഷിച്ച്, ബ്രൗസറിന്റെ പ്രധാന ത്രെഡിലേക്ക് നിയന്ത്രണം തിരികെ നൽകും. ബ്രൗസർ വീണ്ടും ഫ്രീയാകുമ്പോൾ, റിയാക്ടിന് നിർത്തിയിടത്ത് നിന്ന് തന്നെ പുനരാരംഭിക്കാൻ കഴിയും.
ഈ ഘട്ടത്തിൽ, മാറ്റങ്ങളൊന്നും DOM-ലേക്ക് ഫ്ലഷ് ചെയ്യുന്നില്ല. ഉപയോക്താവ് പഴയ, സ്ഥിരതയുള്ള UI കാണുന്നു. ഇത് നിർണായകമാണ് — റിയാക്ട് മാറ്റങ്ങൾ ഘട്ടം ഘട്ടമായി പ്രയോഗിച്ചിരുന്നെങ്കിൽ, ഉപയോക്താവ് തകർന്ന, പാതി റെൻഡർ ചെയ്ത ഒരു ഇന്റർഫേസ് കാണുമായിരുന്നു. എല്ലാ മ്യൂട്ടേഷനുകളും മെമ്മറിയിൽ കണക്കാക്കുകയും ശേഖരിക്കുകയും ചെയ്യുന്നു, കമ്മിറ്റ് ഘട്ടത്തിനായി കാത്തിരിക്കുന്നു.
ഘട്ടം 2: കമ്മിറ്റ് ഘട്ടം (സിൻക്രണസും തടസ്സപ്പെടുത്താനാവാത്തതും)
റെൻഡർ ഘട്ടം മുഴുവൻ അപ്ഡേറ്റ് ചെയ്ത ട്രീക്ക് വേണ്ടി തടസ്സങ്ങളില്ലാതെ പൂർത്തിയായിക്കഴിഞ്ഞാൽ, റിയാക്ട് കമ്മിറ്റ് ഘട്ടത്തിലേക്ക് നീങ്ങുന്നു. ഈ ഘട്ടത്തിൽ, അത് ശേഖരിച്ച സൈഡ് എഫക്റ്റുകളുടെ ലിസ്റ്റ് എടുത്ത് DOM-ൽ പ്രയോഗിക്കുന്നു.
ഈ ഘട്ടം സിൻക്രണസും തടസ്സപ്പെടുത്താൻ കഴിയാത്തതുമാണ്. DOM അറ്റോമിക് ആയി അപ്ഡേറ്റ് ചെയ്യപ്പെടുന്നുവെന്ന് ഉറപ്പാക്കാൻ ഇത് ഒരൊറ്റ, വേഗതയേറിയ ഘട്ടത്തിൽ നടപ്പിലാക്കേണ്ടതുണ്ട്. ഇത് ഉപയോക്താവ് ഒരിക്കലും പൊരുത്തമില്ലാത്തതോ ഭാഗികമായി അപ്ഡേറ്റ് ചെയ്തതോ ആയ ഒരു UI കാണുന്നത് തടയുന്നു. `componentDidMount`, `componentDidUpdate` പോലുള്ള ലൈഫ് സൈക്കിൾ മെത്തേഡുകളും `useLayoutEffect` ഹുക്കും റിയാക്ട് പ്രവർത്തിപ്പിക്കുന്നത് ഈ സമയത്താണ്. ഇത് സിൻക്രണസ് ആയതിനാൽ, `useLayoutEffect`-ൽ ദീർഘനേരം പ്രവർത്തിക്കുന്ന കോഡ് ഒഴിവാക്കണം, കാരണം അത് പെയിന്റിംഗിനെ തടസ്സപ്പെടുത്തും.
കമ്മിറ്റ് ഘട്ടം പൂർത്തിയായി DOM അപ്ഡേറ്റ് ചെയ്ത ശേഷം, `useEffect` ഹുക്കുകൾ അസിൻക്രണസായി പ്രവർത്തിക്കാൻ റിയാക്ട് ഷെഡ്യൂൾ ചെയ്യുന്നു. ഇത് `useEffect`-നുള്ളിലെ ഏതെങ്കിലും കോഡ് (ഡാറ്റാ ഫെച്ചിംഗ് പോലുള്ളവ) ബ്രൗസറിന് അപ്ഡേറ്റ് ചെയ്ത UI സ്ക്രീനിൽ പെയിന്റ് ചെയ്യുന്നതിൽ നിന്ന് തടസ്സപ്പെടുത്തുന്നില്ലെന്ന് ഉറപ്പാക്കുന്നു.
പ്രായോഗിക പ്രത്യാഘാതങ്ങളും API നിയന്ത്രണവും
സിദ്ധാന്തം മനസ്സിലാക്കുന്നത് നല്ലതാണ്, എന്നാൽ ആഗോള ടീമുകളിലെ ഡെവലപ്പർമാർക്ക് ഈ ശക്തമായ സിസ്റ്റം എങ്ങനെ പ്രയോജനപ്പെടുത്താം? റിയാക്ട് 18 റെൻഡറിംഗ് പ്രയോറിറ്റിയിൽ ഡെവലപ്പർമാർക്ക് നേരിട്ടുള്ള നിയന്ത്രണം നൽകുന്ന നിരവധി API-കൾ അവതരിപ്പിച്ചു.
ഓട്ടോമാറ്റിക് ബാച്ചിംഗ്
റിയാക്ട് 18-ൽ, എല്ലാ സ്റ്റേറ്റ് അപ്ഡേറ്റുകളും എവിടെ നിന്ന് വന്നാലും യാന്ത്രികമായി ബാച്ച് ചെയ്യപ്പെടുന്നു. മുമ്പ്, റിയാക്ട് ഇവന്റ് ഹാൻഡ്ലറുകൾക്കുള്ളിലെ അപ്ഡേറ്റുകൾ മാത്രമേ ബാച്ച് ചെയ്തിരുന്നുള്ളൂ. പ്രോമിസുകൾ, `setTimeout`, അല്ലെങ്കിൽ നേറ്റീവ് ഇവന്റ് ഹാൻഡ്ലറുകൾക്കുള്ളിലെ അപ്ഡേറ്റുകൾ ഓരോന്നും വെവ്വേറെ റീ-റെൻഡറിന് കാരണമാകുമായിരുന്നു. ഇപ്പോൾ, ഷെഡ്യൂളറിന് നന്ദി, റിയാക്ട് ഒരു "ടിക്ക്" കാത്തിരിക്കുകയും ആ ടിക്കിനുള്ളിൽ സംഭവിക്കുന്ന എല്ലാ സ്റ്റേറ്റ് അപ്ഡേറ്റുകളെയും ഒരൊറ്റ, ഒപ്റ്റിമൈസ് ചെയ്ത റീ-റെൻഡറിലേക്ക് ബാച്ച് ചെയ്യുകയും ചെയ്യുന്നു. ഇത് അനാവശ്യമായ റെൻഡറുകൾ കുറയ്ക്കുകയും സ്ഥിരമായി പ്രകടനം മെച്ചപ്പെടുത്തുകയും ചെയ്യുന്നു.
startTransition
API
റെൻഡറിംഗ് പ്രയോറിറ്റി നിയന്ത്രിക്കുന്നതിനുള്ള ഏറ്റവും പ്രധാനപ്പെട്ട API ഇതായിരിക്കാം. `startTransition` ഒരു പ്രത്യേക സ്റ്റേറ്റ് അപ്ഡേറ്റിനെ അടിയന്തിരമല്ലാത്തത് അല്ലെങ്കിൽ ഒരു "ട്രാൻസിഷൻ" എന്ന് അടയാളപ്പെടുത്താൻ നിങ്ങളെ അനുവദിക്കുന്നു.
ഒരു സെർച്ച് ഇൻപുട്ട് ഫീൽഡ് സങ്കൽപ്പിക്കുക. ഉപയോക്താവ് ടൈപ്പ് ചെയ്യുമ്പോൾ, രണ്ട് കാര്യങ്ങൾ സംഭവിക്കണം: 1. പുതിയ അക്ഷരം കാണിക്കുന്നതിന് ഇൻപുട്ട് ഫീൽഡ് തന്നെ അപ്ഡേറ്റ് ചെയ്യണം (ഉയർന്ന പ്രയോറിറ്റി). 2. സെർച്ച് ഫലങ്ങളുടെ ഒരു ലിസ്റ്റ് ഫിൽട്ടർ ചെയ്ത് വീണ്ടും റെൻഡർ ചെയ്യണം, ഇത് ഒരു വേഗത കുറഞ്ഞ പ്രവർത്തനമായിരിക്കാം (കുറഞ്ഞ പ്രയോറിറ്റി).
`startTransition` ഇല്ലാതെ, രണ്ട് അപ്ഡേറ്റുകൾക്കും ഒരേ പ്രയോറിറ്റി ആയിരിക്കും, കൂടാതെ വേഗത കുറഞ്ഞ റെൻഡറിംഗ് ലിസ്റ്റ് ഇൻപുട്ട് ഫീൽഡ് ലാഗ് ചെയ്യാൻ കാരണമാവുകയും, മോശം ഉപയോക്തൃ അനുഭവം സൃഷ്ടിക്കുകയും ചെയ്യും. ലിസ്റ്റ് അപ്ഡേറ്റ് `startTransition`-ൽ പൊതിയുന്നതിലൂടെ, നിങ്ങൾ റിയാക്ടിനോട് പറയുന്നു: "ഈ അപ്ഡേറ്റ് അത്ര നിർണായകമല്ല. നിങ്ങൾ പുതിയത് തയ്യാറാക്കുമ്പോൾ പഴയ ലിസ്റ്റ് അല്പനേരം കാണിക്കുന്നത് പ്രശ്നമല്ല. ഇൻപുട്ട് ഫീൽഡ് റെസ്പോൺസീവ് ആക്കുന്നതിന് മുൻഗണന നൽകുക."
ഇവിടെ ഒരു പ്രായോഗിക ഉദാഹരണം:
Loading search results...
import { useState, useTransition } from 'react';
function SearchPage() {
const [isPending, startTransition] = useTransition();
const [inputValue, setInputValue] = useState('');
const [searchQuery, setSearchQuery] = useState('');
const handleInputChange = (e) => {
// ഉയർന്ന പ്രയോറിറ്റിയുള്ള അപ്ഡേറ്റ്: ഇൻപുട്ട് ഫീൽഡ് ഉടൻ അപ്ഡേറ്റ് ചെയ്യുക
setInputValue(e.target.value);
// കുറഞ്ഞ പ്രയോറിറ്റിയുള്ള അപ്ഡേറ്റ്: വേഗത കുറഞ്ഞ സ്റ്റേറ്റ് അപ്ഡേറ്റ് ഒരു ട്രാൻസിഷനിൽ പൊതിയുക
startTransition(() => {
setSearchQuery(e.target.value);
});
};
return (
ഈ കോഡിൽ, `setInputValue` ഒരു ഉയർന്ന പ്രയോറിറ്റിയുള്ള അപ്ഡേറ്റാണ്, ഇത് ഇൻപുട്ട് ഒരിക്കലും ലാഗ് ചെയ്യുന്നില്ലെന്ന് ഉറപ്പാക്കുന്നു. `setSearchQuery`, വേഗത കുറഞ്ഞ `SearchResults` കമ്പോണന്റിനെ റീ-റെൻഡർ ചെയ്യാൻ പ്രേരിപ്പിക്കുന്നത്, ഒരു ട്രാൻസിഷനായി അടയാളപ്പെടുത്തിയിരിക്കുന്നു. ഉപയോക്താവ് വീണ്ടും ടൈപ്പ് ചെയ്താൽ റിയാക്ടിന് ഈ ട്രാൻസിഷൻ തടസ്സപ്പെടുത്താനും, കാലഹരണപ്പെട്ട റെൻഡർ വർക്ക് ഉപേക്ഷിച്ച് പുതിയ ക്വറിയുമായി പുതുതായി ആരംഭിക്കാനും കഴിയും. `useTransition` ഹുക്ക് നൽകുന്ന `isPending` ഫ്ലാഗ് ഈ ട്രാൻസിഷൻ സമയത്ത് ഉപയോക്താവിന് ഒരു ലോഡിംഗ് സ്റ്റേറ്റ് കാണിക്കുന്നതിനുള്ള സൗകര്യപ്രദമായ മാർഗമാണ്.
useDeferredValue
ഹുക്ക്
`useDeferredValue` സമാനമായ ഒരു ഫലം നേടുന്നതിന് മറ്റൊരു മാർഗ്ഗം നൽകുന്നു. ട്രീയുടെ അപ്രധാനമായ ഒരു ഭാഗത്തിന്റെ റീ-റെൻഡറിംഗ് മാറ്റിവയ്ക്കാൻ ഇത് നിങ്ങളെ അനുവദിക്കുന്നു. ഇത് ഒരു ഡിബൗൺസ് പ്രയോഗിക്കുന്നത് പോലെയാണ്, പക്ഷേ ഇത് റിയാക്ടിന്റെ ഷെഡ്യൂളറുമായി നേരിട്ട് സംയോജിപ്പിച്ചിരിക്കുന്നതിനാൽ വളരെ മികച്ചതാണ്.
ഇതൊരു വാല്യൂ എടുത്ത് അതിന്റെ ഒരു പുതിയ പകർപ്പ് നൽകുന്നു, അത് ഒരു റെൻഡർ സമയത്ത് യഥാർത്ഥത്തിൽ നിന്ന് "പിന്നോട്ട് പോകും". നിലവിലെ റെൻഡർ ഒരു അടിയന്തിര അപ്ഡേറ്റ് (ഉപയോക്തൃ ഇൻപുട്ട് പോലുള്ളവ) വഴി ട്രിഗർ ചെയ്തതാണെങ്കിൽ, റിയാക്ട് ആദ്യം പഴയ, ഡിഫേർഡ് വാല്യൂ ഉപയോഗിച്ച് റെൻഡർ ചെയ്യുകയും തുടർന്ന് കുറഞ്ഞ പ്രയോറിറ്റിയിൽ പുതിയ വാല്യൂ ഉപയോഗിച്ച് ഒരു റീ-റെൻഡർ ഷെഡ്യൂൾ ചെയ്യുകയും ചെയ്യും.
`useDeferredValue` ഉപയോഗിച്ച് സെർച്ച് ഉദാഹരണം നമുക്ക് റീഫാക്ടർ ചെയ്യാം:
import { useState, useDeferredValue } from 'react';
function SearchPage() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const handleInputChange = (e) => {
setQuery(e.target.value);
};
return (
ഇവിടെ, `input` എല്ലായ്പ്പോഴും ഏറ്റവും പുതിയ `query` ഉപയോഗിച്ച് അപ്-ടു-ഡേറ്റ് ആണ്. എന്നിരുന്നാലും, `SearchResults`-ന് `deferredQuery` ലഭിക്കുന്നു. ഉപയോക്താവ് വേഗത്തിൽ ടൈപ്പ് ചെയ്യുമ്പോൾ, ഓരോ കീസ്ട്രോക്കിലും `query` അപ്ഡേറ്റ് ചെയ്യുന്നു, എന്നാൽ `deferredQuery` അതിന്റെ മുൻ മൂല്യം റിയാക്ടിന് അല്പം സമയം കിട്ടുന്നത് വരെ നിലനിർത്തും. ഇത് ലിസ്റ്റിന്റെ റെൻഡറിംഗിന് മുൻഗണന കുറയ്ക്കുകയും UI സുഗമമായി നിലനിർത്തുകയും ചെയ്യുന്നു.
പ്രയോറിറ്റി ലെയ്നുകൾ ദൃശ്യവൽക്കരിക്കുന്നു: ഒരു മാനസിക മാതൃക
ഈ മാനസിക മാതൃക ഉറപ്പിക്കുന്നതിനായി നമുക്ക് ഒരു സങ്കീർണ്ണമായ സാഹചര്യം പരിശോധിക്കാം. ഒരു സോഷ്യൽ മീഡിയ ഫീഡ് ആപ്ലിക്കേഷൻ സങ്കൽപ്പിക്കുക:
- പ്രാരംഭ അവസ്ഥ: ഉപയോക്താവ് പോസ്റ്റുകളുടെ ഒരു നീണ്ട ലിസ്റ്റിലൂടെ സ്ക്രോൾ ചെയ്യുന്നു. ഇത് പുതിയ ഇനങ്ങൾ കാഴ്ചയിലേക്ക് വരുമ്പോൾ റെൻഡർ ചെയ്യുന്നതിനായി `NormalPriority` അപ്ഡേറ്റുകൾ ട്രിഗർ ചെയ്യുന്നു.
- ഉയർന്ന പ്രയോറിറ്റിയുള്ള തടസ്സം: സ്ക്രോൾ ചെയ്യുമ്പോൾ, ഉപയോക്താവ് ഒരു പോസ്റ്റിന്റെ കമന്റ് ബോക്സിൽ ഒരു കമന്റ് ടൈപ്പ് ചെയ്യാൻ തീരുമാനിക്കുന്നു. ഈ ടൈപ്പിംഗ് പ്രവർത്തനം ഇൻപുട്ട് ഫീൽഡിലേക്ക് `ImmediatePriority` അപ്ഡേറ്റുകൾ ട്രിഗർ ചെയ്യുന്നു.
- കൺകറന്റ് കുറഞ്ഞ പ്രയോറിറ്റിയുള്ള ജോലി: കമന്റ് ബോക്സിൽ ഫോർമാറ്റ് ചെയ്ത ടെക്സ്റ്റിന്റെ ഒരു ലൈവ് പ്രിവ്യൂ കാണിക്കുന്ന ഒരു ഫീച്ചർ ഉണ്ടാകാം. ഈ പ്രിവ്യൂ റെൻഡർ ചെയ്യുന്നത് വേഗത കുറഞ്ഞതാകാം. പ്രിവ്യൂവിനായുള്ള സ്റ്റേറ്റ് അപ്ഡേറ്റ് നമുക്ക് ഒരു `startTransition`-ൽ പൊതിയാം, ഇത് ഒരു `LowPriority` അപ്ഡേറ്റാക്കി മാറ്റുന്നു.
- പശ്ചാത്തല അപ്ഡേറ്റ്: ഒരേ സമയം, പുതിയ പോസ്റ്റുകൾക്കായുള്ള ഒരു പശ്ചാത്തല `fetch` കോൾ പൂർത്തിയാകുന്നു, ഇത് ഫീഡിന്റെ മുകളിൽ "New Posts Available" ബാനർ ചേർക്കുന്നതിനായി മറ്റൊരു `NormalPriority` സ്റ്റേറ്റ് അപ്ഡേറ്റ് ട്രിഗർ ചെയ്യുന്നു.
റിയാക്ടിന്റെ ഷെഡ്യൂളർ ഈ ട്രാഫിക് എങ്ങനെ കൈകാര്യം ചെയ്യുമെന്ന് നോക്കാം:
- റിയാക്ട് ഉടൻ തന്നെ `NormalPriority` സ്ക്രോൾ റെൻഡറിംഗ് ജോലി താൽക്കാലികമായി നിർത്തുന്നു.
- ഇത് `ImmediatePriority` ഇൻപുട്ട് അപ്ഡേറ്റുകൾ തൽക്ഷണം കൈകാര്യം ചെയ്യുന്നു. ഉപയോക്താവിന്റെ ടൈപ്പിംഗ് പൂർണ്ണമായും റെസ്പോൺസീവ് ആയി അനുഭവപ്പെടുന്നു.
- ഇത് പശ്ചാത്തലത്തിൽ `LowPriority` കമന്റ് പ്രിവ്യൂ റെൻഡറിൽ ജോലി ആരംഭിക്കുന്നു.
- `fetch` കോൾ പൂർത്തിയാവുകയും, ബാനറിനായി ഒരു `NormalPriority` അപ്ഡേറ്റ് ഷെഡ്യൂൾ ചെയ്യുകയും ചെയ്യുന്നു. ഇതിന് കമന്റ് പ്രിവ്യൂവിനേക്കാൾ ഉയർന്ന പ്രയോറിറ്റിയുള്ളതിനാൽ, റിയാക്ട് പ്രിവ്യൂ റെൻഡറിംഗ് താൽക്കാലികമായി നിർത്തി, ബാനർ അപ്ഡേറ്റിൽ പ്രവർത്തിച്ച്, അത് DOM-ലേക്ക് കമ്മിറ്റ് ചെയ്യുകയും, തുടർന്ന് ഒഴിവു സമയം കിട്ടുമ്പോൾ പ്രിവ്യൂ റെൻഡറിംഗ് പുനരാരംഭിക്കുകയും ചെയ്യും.
- എല്ലാ ഉപയോക്തൃ ഇടപെടലുകളും ഉയർന്ന പ്രയോറിറ്റിയുള്ള ജോലികളും പൂർത്തിയായിക്കഴിഞ്ഞാൽ, റിയാക്ട് യഥാർത്ഥ `NormalPriority` സ്ക്രോൾ റെൻഡറിംഗ് ജോലി നിർത്തിയിടത്ത് നിന്ന് പുനരാരംഭിക്കുന്നു.
ഈ ചലനാത്മകമായ താൽക്കാലികമായി നിർത്തൽ, മുൻഗണന നൽകൽ, പുനരാരംഭിക്കൽ എന്നിവയാണ് പ്രയോറിറ്റി ലെയ്ൻ മാനേജ്മെന്റിന്റെ സത്ത. ഏറ്റവും നിർണായകമായ ഇടപെടലുകൾ കുറഞ്ഞ നിർണായക പശ്ചാത്തല ജോലികളാൽ ഒരിക്കലും തടസ്സപ്പെടുന്നില്ലെന്ന് ഇത് ഉറപ്പാക്കുന്നു, അതിനാൽ ഉപയോക്താവിന്റെ പ്രകടനത്തെക്കുറിച്ചുള്ള ധാരണ എല്ലായ്പ്പോഴും ഒപ്റ്റിമൈസ് ചെയ്യപ്പെടുന്നു.
ആഗോള സ്വാധീനം: വേഗതയ്ക്ക് അപ്പുറം
റിയാക്ടിന്റെ കൺകറന്റ് റെൻഡറിംഗ് മോഡലിന്റെ പ്രയോജനങ്ങൾ ആപ്ലിക്കേഷനുകൾക്ക് വേഗത നൽകുന്നതിനപ്പുറം വ്യാപിക്കുന്നു. ആഗോള ഉപയോക്താക്കൾക്കായി പ്രധാനപ്പെട്ട ബിസിനസ്സ്, ഉൽപ്പന്ന അളവുകളിൽ അവയ്ക്ക് വ്യക്തമായ സ്വാധീനമുണ്ട്.
- പ്രവേശനക്ഷമത (Accessibility): ഒരു റെസ്പോൺസീവ് UI ഒരു പ്രവേശനക്ഷമതയുള്ള UI ആണ്. ഒരു ഇന്റർഫേസ് ഫ്രീസ് ചെയ്യുമ്പോൾ, അത് എല്ലാ ഉപയോക്താക്കൾക്കും ആശയക്കുഴപ്പമുണ്ടാക്കുകയും ഉപയോഗശൂന്യമാക്കുകയും ചെയ്യും, എന്നാൽ സ്ക്രീൻ റീഡറുകൾ പോലുള്ള സഹായ സാങ്കേതികവിദ്യകളെ ആശ്രയിക്കുന്നവർക്ക് ഇത് പ്രത്യേകിച്ചും പ്രശ്നമാണ്, കാരണം അവർക്ക് സന്ദർഭം നഷ്ടപ്പെടുകയോ പ്രതികരണശേഷിയില്ലാതാവുകയോ ചെയ്യാം.
- ഉപയോക്തൃ നിലനിർത്തൽ (User Retention): മത്സരാധിഷ്ഠിത ഡിജിറ്റൽ ലോകത്ത്, പ്രകടനം ഒരു ഫീച്ചറാണ്. വേഗത കുറഞ്ഞതും ജാങ്കിയുമായ ആപ്ലിക്കേഷനുകൾ ഉപയോക്തൃ നിരാശയിലേക്കും, ഉയർന്ന ബൗൺസ് നിരക്കുകളിലേക്കും, കുറഞ്ഞ ഇടപഴകലിലേക്കും നയിക്കുന്നു. ഒരു സുഗമമായ അനുഭവം ആധുനിക സോഫ്റ്റ്വെയറിന്റെ ഒരു പ്രധാന പ്രതീക്ഷയാണ്.
- ഡെവലപ്പർ അനുഭവം (Developer Experience): ഈ ശക്തമായ ഷെഡ്യൂളിംഗ് പ്രിമിറ്റീവുകൾ ലൈബ്രറിയിൽ തന്നെ നിർമ്മിക്കുന്നതിലൂടെ, സങ്കീർണ്ണവും മികച്ച പ്രകടനവുമുള്ള UI-കൾ കൂടുതൽ ഡിക്ലറേറ്റീവായി നിർമ്മിക്കാൻ റിയാക്ട് ഡെവലപ്പർമാരെ അനുവദിക്കുന്നു. സങ്കീർണ്ണമായ ഡിബൗൺസിംഗ്, ത്രോട്ടിലിംഗ്, അല്ലെങ്കിൽ `requestIdleCallback` ലോജിക് സ്വമേധയാ നടപ്പിലാക്കുന്നതിനുപകരം, ഡെവലപ്പർമാർക്ക് `startTransition` പോലുള്ള API-കൾ ഉപയോഗിച്ച് റിയാക്ടിനോട് അവരുടെ ഉദ്ദേശ്യം സൂചിപ്പിക്കാൻ കഴിയും, ഇത് വൃത്തിയുള്ളതും പരിപാലിക്കാൻ എളുപ്പമുള്ളതുമായ കോഡിലേക്ക് നയിക്കുന്നു.
ആഗോള ഡെവലപ്മെന്റ് ടീമുകൾക്കുള്ള പ്രായോഗിക നിർദ്ദേശങ്ങൾ
- കൺകറൻസി സ്വീകരിക്കുക: നിങ്ങളുടെ ടീം റിയാക്ട് 18 ഉപയോഗിക്കുന്നുണ്ടെന്നും പുതിയ കൺകറന്റ് ഫീച്ചറുകൾ മനസ്സിലാക്കുന്നുണ്ടെന്നും ഉറപ്പാക്കുക. ഇത് ഒരു മാതൃകാപരമായ മാറ്റമാണ്.
- ട്രാൻസിഷനുകൾ തിരിച്ചറിയുക: അടിയന്തിരമല്ലാത്ത ഏതെങ്കിലും UI അപ്ഡേറ്റുകൾക്കായി നിങ്ങളുടെ ആപ്ലിക്കേഷൻ ഓഡിറ്റ് ചെയ്യുക. കൂടുതൽ നിർണായകമായ ഇടപെടലുകളെ തടസ്സപ്പെടുത്താതിരിക്കാൻ അനുബന്ധ സ്റ്റേറ്റ് അപ്ഡേറ്റുകൾ `startTransition`-ൽ പൊതിയുക.
- ഭാരമേറിയ റെൻഡറുകൾ മാറ്റിവയ്ക്കുക: റെൻഡർ ചെയ്യാൻ വേഗത കുറഞ്ഞതും വേഗത്തിൽ മാറുന്ന ഡാറ്റയെ ആശ്രയിക്കുന്നതുമായ കമ്പോണന്റുകൾക്കായി, അവയുടെ റീ-റെൻഡറിംഗിന് മുൻഗണന കുറയ്ക്കാനും ആപ്ലിക്കേഷന്റെ മറ്റ് ഭാഗങ്ങൾ വേഗത്തിലാക്കാനും `useDeferredValue` ഉപയോഗിക്കുക.
- പ്രൊഫൈൽ ചെയ്യുകയും അളക്കുകയും ചെയ്യുക: നിങ്ങളുടെ കമ്പോണന്റുകൾ എങ്ങനെ റെൻഡർ ചെയ്യുന്നുവെന്ന് ദൃശ്യവൽക്കരിക്കാൻ റിയാക്ട് ഡെവലപ്പർ ടൂൾസ് പ്രൊഫൈലർ ഉപയോഗിക്കുക. പ്രൊഫൈലർ കൺകറന്റ് റിയാക്ടിനായി അപ്ഡേറ്റ് ചെയ്തിട്ടുണ്ട്, കൂടാതെ ഏതൊക്കെ അപ്ഡേറ്റുകളാണ് തടസ്സപ്പെടുന്നതെന്നും ഏതൊക്കെയാണ് പ്രകടന തടസ്സങ്ങൾക്ക് കാരണമാകുന്നതെന്നും തിരിച്ചറിയാൻ ഇത് നിങ്ങളെ സഹായിക്കും.
- വിദ്യാഭ്യാസം നൽകുകയും പ്രചരിപ്പിക്കുകയും ചെയ്യുക: ഈ ആശയങ്ങൾ നിങ്ങളുടെ ടീമിനുള്ളിൽ പ്രോത്സാഹിപ്പിക്കുക. മികച്ച പ്രകടനമുള്ള ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നത് ഒരു കൂട്ടായ ഉത്തരവാദിത്തമാണ്, ഒപ്റ്റിമൽ കോഡ് എഴുതുന്നതിന് റിയാക്ടിന്റെ ഷെഡ്യൂളറിനെക്കുറിച്ചുള്ള ഒരു പൊതുവായ ധാരണ നിർണായകമാണ്.
ഉപസംഹാരം
റിയാക്ട് ഫൈബറും അതിന്റെ പ്രയോറിറ്റി അടിസ്ഥാനമാക്കിയുള്ള ഷെഡ്യൂളറും ഫ്രണ്ട്-എൻഡ് ഫ്രെയിംവർക്കുകളുടെ പരിണാമത്തിലെ ഒരു വലിയ കുതിച്ചുചാട്ടത്തെ പ്രതിനിധീകരിക്കുന്നു. തടസ്സപ്പെടുത്തുന്ന, സിൻക്രണസ് റെൻഡറിംഗിന്റെ ലോകത്ത് നിന്ന് നമ്മൾ സഹകരണപരവും തടസ്സപ്പെടുത്താവുന്നതുമായ ഷെഡ്യൂളിംഗിന്റെ ഒരു പുതിയ മാതൃകയിലേക്ക് മാറിയിരിക്കുന്നു. ജോലിയെ കൈകാര്യം ചെയ്യാവുന്ന ഫൈബർ കഷണങ്ങളായി വിഭജിക്കുകയും ആ ജോലിക്ക് മുൻഗണന നൽകുന്നതിന് സങ്കീർണ്ണമായ ഒരു ലെയ്ൻ മോഡൽ ഉപയോഗിക്കുകയും ചെയ്യുന്നതിലൂടെ, ഉപയോക്താവിന് അഭിമുഖീകരിക്കുന്ന ഇടപെടലുകൾ എല്ലായ്പ്പോഴും ആദ്യം കൈകാര്യം ചെയ്യപ്പെടുന്നുവെന്ന് റിയാക്ടിന് ഉറപ്പാക്കാൻ കഴിയും, പശ്ചാത്തലത്തിൽ സങ്കീർണ്ണമായ ജോലികൾ ചെയ്യുമ്പോൾ പോലും സുഗമവും തൽക്ഷണവുമായി അനുഭവപ്പെടുന്ന ആപ്ലിക്കേഷനുകൾ സൃഷ്ടിക്കുന്നു.
ഡെവലപ്പർമാരെ സംബന്ധിച്ചിടത്തോളം, ട്രാൻസിഷനുകളും ഡിഫേർഡ് വാല്യൂകളും പോലുള്ള ആശയങ്ങളിൽ വൈദഗ്ദ്ധ്യം നേടുന്നത് ഇനി ഒരു ഓപ്ഷണൽ ഒപ്റ്റിമൈസേഷനല്ല — ഇത് ആധുനികവും ഉയർന്ന പ്രകടനവുമുള്ള വെബ് ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിനുള്ള ഒരു പ്രധാന കഴിവാണത്. റിയാക്ടിന്റെ പ്രയോറിറ്റി ലെയ്ൻ മാനേജ്മെന്റ് മനസ്സിലാക്കുകയും പ്രയോജനപ്പെടുത്തുകയും ചെയ്യുന്നതിലൂടെ, നിങ്ങൾക്ക് ആഗോള പ്രേക്ഷകർക്ക് മികച്ച ഉപയോക്തൃ അനുഭവം നൽകാൻ കഴിയും, ഇത് പ്രവർത്തനക്ഷമം മാത്രമല്ല, ഉപയോഗിക്കാൻ ശരിക്കും സന്തോഷം നൽകുന്ന ഇന്റർഫേസുകൾ നിർമ്മിക്കുന്നു.